home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Applications / DataScope 2.0.3 / DataScope2l / DSSource / ftwin.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-04  |  44.1 KB  |  1,802 lines  |  [TEXT/MPS ]

  1. #define __ALLNU__
  2. # include <types.h>                 /* Nearly always required */
  3. # include <quickdraw.h>             /* To access the qd globals */
  4. # include <toolutils.h>             /* CursHandle and iBeamCursor */
  5. # include <fonts.h>                 /* Only for InitFonts() trap */
  6. # include <events.h>                /* GetNextEvent(), ... */
  7. # include <windows.h>                /* GetNewWindow(), ... */
  8. # include <controls.h>
  9. # include <files.h>
  10. # include <fcntl.h>
  11. # include <packages.h>
  12. # include <dialogs.h>                /* InitDialogs() and GetNewDialog() */
  13. # include <menus.h>                 /* EnableItem(), DisableItem() */
  14. # include <desk.h>                    /* SystemTask(), SystemClick() */
  15. # include <textedit.h>                /* TENew() */
  16. # include <scrap.h>                 /* ZeroScrap() */
  17. # include <segload.h>                /* UnloadSeg() */
  18. # include <StdIO.h>
  19. # include <StdLib.h>
  20. # include <Math.h>
  21. # include <Palette.h>
  22.  
  23. #include "fview.h"
  24.  
  25. extern
  26. struct Mwin *mw,*Mlist;        /* Mwin list and temporary pointer */
  27. extern
  28. Point startwin;
  29.  
  30. extern char *rgbsave;
  31. extern
  32. RgnHandle Urgn;                /* storage for update region */
  33.  
  34. /*
  35. *  IDs for scroll bar controls
  36. */
  37. # define vbarID    300
  38. # define hbarID 301
  39.  
  40. # define windowID        128
  41. # define imgwinID      129
  42.  
  43. /*
  44.  *    This routine handles autorepeat scrolling.
  45.  */
  46.  
  47. pascal void DoAutoScroll (ControlHandle, short);
  48. pascal void DoAutoScroll (theCtl, part)
  49.     ControlHandle        theCtl;
  50.     short                part;
  51. {
  52.     struct Mwin *tw;
  53.     struct fdatawin *td;
  54.     struct ftextwin *tc;
  55.     int r, oldl,oldt;
  56.     
  57.     /* get the data structure. */
  58.     tw = findm(FrontWindow());
  59.     td = tw->dat;                    /* help for later de-referencing */
  60.     tc = tw->cw;                    /* text window data */
  61.     oldl = tc->offl;
  62.     oldt = tc->offt;
  63.     
  64.     /* which scroll bar is it? */
  65.     if (theCtl == tc->hbar)
  66.         {        /* horiz scroll bar. */
  67.         switch (part)
  68.             {
  69.             case inUpButton:
  70.                 tc->offl--;  break;
  71.             case inDownButton:
  72.                 tc->offl++;  break;
  73.             case inPageUp:
  74.                 tc->offl -= tc->ccount.h-1;  break;
  75.             case inPageDown:
  76.                 tc->offl += tc->ccount.h-1;  break;
  77.             case inThumb:
  78.                 r = GetCtlValue(theCtl);
  79.                 tc->offl = r*td->xdim/1000;            /* offset from left */
  80.                 break;
  81.             }
  82.         if (tc->offl < 0) tc->offl = 0;
  83.         if (tc->offl >= td->xdim) tc->offl = td->xdim-1;
  84.         }
  85.     else 
  86.         {
  87.         switch (part) 
  88.             {
  89.             case inUpButton:
  90.                 tc->offt--;  break;
  91.             case inDownButton:
  92.                 tc->offt++;  break;
  93.             case inPageUp:
  94.                 tc->offt -= tc->ccount.v-1;  break;
  95.             case inPageDown:
  96.                 tc->offt += tc->ccount.v-1;  break;
  97.             case inThumb:
  98.                 r = GetCtlValue(theCtl);
  99.                 tc->offt = r*td->ydim/1000;            /* offset from left */
  100.                 break;
  101.             }
  102.         if (tc->offt < 0) tc->offt = 0;
  103.         if (tc->offt >= td->ydim) tc->offt = td->ydim-1;
  104.         }
  105. /*
  106. *  Call the scroll routine which scrolls and then invalidates the remaining area of
  107. *  the window, so that update will fill in missing areas.
  108. *  Also call routine which invalidates scroll bars, so they will re-draw.
  109. */
  110.     if (tc->offl != oldl || tc->offt != oldt)
  111.         {
  112.         drawfloat(tw, tc->offl - oldl, tc->offt - oldt); 
  113.         controlfloat (tw);
  114.         }
  115. }
  116.  
  117.  
  118. /************************************************************************************/
  119. /* mousefloat
  120. *  Process the mouse click in a floating point window.
  121. *
  122. */
  123. mousefloat(tw,where,modifiers)
  124.     struct Mwin *tw;
  125.     int modifiers;
  126.     Point *where;
  127.     {
  128.     Point tpt;
  129.     Rect tr;
  130.     ControlHandle aControl;
  131.     int r,i,j,oldl,oldt;
  132.     struct fdatawin *td;
  133.     struct ftextwin *tc;
  134.     
  135.     td = tw->dat;                    /* help for later de-referencing */
  136.     tc = tw->cw;                    /* text window data */
  137.         
  138.     SetPort(tw->win);
  139.     oldl = tc->offl;
  140.     oldt = tc->offt;
  141.     
  142. /*
  143. *  look for control access (scroll bars)
  144. */
  145.     GlobalToLocal(where);                            /* translate to local */
  146.     i = findcontrol( where, tw->win, &aControl);    /* see if it is a control */
  147.     
  148.     if (i) 
  149.         {                                        /* do control actions */
  150.         if (i != inThumb)
  151.             trackcontrol( aControl, where, (ProcPtr) DoAutoScroll);
  152.         else
  153.             {
  154.             if (i = trackcontrol( aControl, where, NULL)) 
  155.                 {
  156.                 if (i == inThumb)
  157.                     if (aControl == tc->hbar)
  158.                         {
  159.                         r = GetCtlValue(aControl);
  160.                         tc->offl = r*td->xdim/1000;            /* offset from left */
  161.                         if (tc->offl < 0) tc->offl = 0;
  162.                         if (tc->offl >= td->xdim) tc->offl = td->xdim-1;
  163.                         }
  164.                     else 
  165.                         {
  166.                         r = GetCtlValue(aControl);
  167.                         tc->offt = r*td->ydim/1000;            /* offset from left */
  168.                         if (tc->offt < 0) tc->offt = 0;
  169.                         if (tc->offt >= td->ydim) tc->offt = td->ydim-1;
  170.                         }
  171. /*
  172. *  Call the scroll routine which scrolls and then invalidates the remaining area of
  173. *  the window, so that update will fill in missing areas.
  174. *  Also call routine which invalidates scroll bars, so they will re-draw.
  175. */
  176.                 if (tc->offl != oldl || tc->offt != oldt) 
  177.                     {
  178.                     drawfloat(tw, tc->offl - oldl, tc->offt - oldt); 
  179.                     inscrfloat(tw);        /* invalidate bars, so they will re-draw */
  180.                     }
  181.                 }
  182.             }
  183.         }
  184.     
  185. /*
  186. *  Not a click in a scrollbar, do the selection.
  187. */
  188.     else {
  189.         tr = tw->win->portRect;
  190.         tr.top = 0;
  191.         tr.left = 0;
  192.         tr.bottom -= 15;
  193.         tr.right -= 15;
  194.         if (!ptinrect(where, &tr))                /* make sure not in grow box */
  195.             return;
  196.         
  197.         pttocell(tw,where);                        /* find cell #s */
  198.         if (!(modifiers & shiftKey) ||
  199.             tc->sel.top < 0) {                    /* zero selection to start */
  200.             for (i= tc->sel.top; i<=tc->sel.bottom; i++)        /* remove visible old selection */
  201.                 for (j=tc->sel.left; j<= tc->sel.right; j++)
  202.                     invertfloat(tw,j,i);
  203.             tc->sel.top = tc->sel.bottom = where->v;
  204.             tc->sel.left = tc->sel.right = where->h;
  205.             tc->selanchor = *where;                /* keep the anchor point */
  206.             invertfloat(tw,where->h,where->v);    /* make it reverse */
  207.  
  208.         }
  209. /*
  210. *  Special behavior with shift-select.  If the mouse is outside of the region, move
  211. *  the anchor to the far point in the selection.
  212. */
  213.         else {
  214.             if (where->v <= tc->sel.top)                /* point above selection */
  215.                 tc->selanchor.v = tc->sel.bottom;        /* set anchor to bottom of selection */
  216.             else if (where->v >= tc->sel.bottom)        /* point below selection */
  217.                 tc->selanchor.v = tc->sel.top;            /* set anchor to top of selection */
  218.             if (where->h <= tc->sel.left)                /* similar for left and right situation */
  219.                 tc->selanchor.h = tc->sel.right;
  220.             else if (where->h >= tc->sel.right)
  221.                 tc->selanchor.h = tc->sel.left;
  222.         }
  223.  
  224. /*
  225. *  While mouse is pressed, extend the selection.  If the shift key was pressed to
  226. *  start the selection, then we are automatically extending the selection.
  227. */
  228.         tpt = tc->selanchor;                /* make a copy of anchor point */
  229.         
  230.         while (StillDown()) {
  231.             GetMouse(where);
  232.             if (!ptinrect(where,&tr)) {            /* Is outside of window, scroll */
  233.                 if (where->h > tr.right && tc->offl < td->xdim - 1) {
  234.                     where->h = tr.right;
  235.                     tc->offl++;
  236.                     drawfloat(tw, 1, 0);
  237.                 }
  238.                 if (where->h < tr.left && tc->offl > 0) {
  239.                     where->h = tr.left;
  240.                     tc->offl--;
  241.                     drawfloat(tw, -1,0);
  242.                 }
  243.                 if (where->v < tr.top && tc->offt > 0) {
  244.                     where->v = tr.top;
  245.                     tc->offt--;
  246.                     drawfloat(tw, 0, -1);
  247.                 }
  248.                 if (where->v > tr.bottom && tc->offt < td->ydim - 1) {
  249.                     where->v = tr.bottom;
  250.                     tc->offt++;
  251.                     drawfloat(tw, 0, 1);
  252.                 }
  253.                     
  254.             }    /* fall through to selection extension */
  255.             {
  256.                 pttocell(tw,where);                /* make relative to data set */
  257.                 
  258.             /* 
  259.             *  determine the direction to extend the selection
  260.             */
  261.                 if (where->v <= tpt.v) {        /* move bottom to anchor, top to point */
  262.                     while (tc->sel.bottom > tpt.v)
  263.                         invrow(tw,tc->sel.bottom--);    /* make it visible */
  264.                     while (tc->sel.top > where->v)
  265.                         invrow(tw,--tc->sel.top);
  266.                     while (tc->sel.top < where->v)
  267.                         invrow(tw,tc->sel.top++);
  268.                 }
  269.                 else {                            /* move top to anchor, bottom to point */
  270.                     while (tc->sel.top < tpt.v)
  271.                         invrow(tw,tc->sel.top++);
  272.                     while (tc->sel.bottom < where->v)
  273.                         invrow(tw,++tc->sel.bottom);
  274.                     while (tc->sel.bottom > where->v)
  275.                         invrow(tw,tc->sel.bottom--);
  276.                 }
  277.                 
  278.                 if (where->h <= tpt.h) {        /* move right to anchor, left to point */
  279.                     while (tc->sel.right > tpt.h)
  280.                         invcol(tw,tc->sel.right--);        /* make it visible */
  281.                     while (tc->sel.left > where->h)
  282.                         invcol(tw,--tc->sel.left);
  283.                     while (tc->sel.left < where->h)
  284.                         invcol(tw,tc->sel.left++);
  285.                 }
  286.                 else {                            /* move left to anchor, right to point */
  287.                     while (tc->sel.left < tpt.h)
  288.                         invcol(tw,tc->sel.left++);
  289.                     while (tc->sel.right < where->h)
  290.                         invcol(tw,++tc->sel.right);
  291.                     while (tc->sel.right > where->h)
  292.                         invcol(tw,tc->sel.right--);
  293.                 }
  294.                 
  295.             }
  296.         }
  297. /*
  298. *  After selection is made, 
  299. *  synch other windows also, including all image windows.
  300. *  But, since I am already updated, don't re-draw me.
  301. */
  302.         synchfloat(tw,&tc->sel,0);
  303.  
  304.     }
  305.  
  306.     
  307.     return(1);
  308. }
  309.  
  310.  
  311. /************************************************************************************/
  312. /*  invrow,invcol
  313. *  invert a row or column of cells during selection.
  314. */
  315. invrow(tw,rown)
  316.     struct Mwin *tw;
  317.     int rown;
  318.     {
  319.     int i;
  320.     
  321.     for (i=tw->cw->sel.left ; i <= tw->cw->sel.right; i++)
  322.         invertfloat(tw, i, rown);
  323. }
  324.  
  325. invcol(tw,coln)
  326.     struct Mwin *tw;
  327.     int coln;
  328.     {
  329.     int i;
  330.     
  331.     for (i=tw->cw->sel.top ; i <= tw->cw->sel.bottom; i++)
  332.         invertfloat(tw, coln, i);
  333. }
  334.  
  335. /************************************************************************************/
  336. /*  pttocell
  337. *   Convert a window-local point to the cell location that the point refers to.
  338. *   Accounts for scroll bar offsets, too.
  339. */
  340. pttocell(tw,thept)
  341.     Point *thept;
  342.     struct Mwin *tw;
  343.     {
  344.     struct ftextwin *tc;
  345.     
  346.     tc = tw->cw;
  347.     
  348.     thept->v = thept->v/tc->csize.v + tc->offt;
  349.     thept->h = thept->h/tc->csize.h + tc->offl;
  350.     
  351.     if (thept->v >= tw->dat->ydim)
  352.         thept->v = tw->dat->ydim - 1;
  353.     if (thept->h >= tw->dat->xdim)
  354.         thept->h = tw->dat->xdim - 1;
  355.     if (thept->v < 0)
  356.         thept->v = 0;
  357.     if (thept->h < 0)
  358.         thept->h = 0;
  359.     
  360. }
  361.  
  362. #define CLORLOWER    1
  363. #define CLORHIGHER    239
  364.  
  365. /*******************************************************************************/
  366. /*  newdatawin
  367. *  Allocate and create a blank datawin record.
  368. *  Fill in blank and default values.
  369. */
  370. struct fdatawin
  371. *newdatawin(varname,xdim,ydim)
  372.     char *varname;
  373.     int xdim,ydim;
  374.     {
  375.     struct fdatawin *td;
  376.     register int i,j;
  377.     
  378. /*
  379. *  do a memory estimate for safety, then malloc the needed memory.
  380. */
  381.     j = (xdim*ydim+xdim+ydim)*sizeof(float) + 5000;
  382.     if (checkmem(j)) 
  383.         return(NULL);
  384.     
  385.     if (NULL == (td = (struct fdatawin *)NewPtr(sizeof(struct fdatawin))))
  386.         return(NULL);
  387.  
  388.     if (NULL == (td->xvals = (float *)NewPtr((xdim+1)*sizeof(float)))
  389.         || NULL == (td->yvals = (float *)NewPtr((ydim+1)*sizeof(float)))
  390.         || NULL == (td->vals = (float *)NewPtr((xdim*ydim)*sizeof(float)))) {
  391.         return(NULL);
  392.     }
  393. /*
  394. *  fill in default fields that may get overridden by later loading of data.
  395. */
  396.     td->xdim = xdim;
  397.     td->ydim = ydim;
  398.     
  399.     strcpy(td->fmt,"%11.4e");            /* set up attribute values */
  400.     strcpy(td->labfmt,"%5.0f");            /* format for column labels */
  401.     td->cmin = 1;
  402.     td->cmax = CLORHIGHER;                        /* default color range */
  403.     
  404.     for (i=strlen(varname)-1; i > 0 && varname[i] == ' '; i--)    /* trim trailing spaces */
  405.             varname[i] = 0;
  406.     strncpy(td->dvar,varname,sizeof(td->dvar)-1);
  407.     td->dvar[sizeof(td->dvar)-1] = 0;    /* trim it to required length */
  408.     for (i=0; i< strlen(td->dvar); i++)
  409.         if (td->dvar[i] < 48 || td->dvar[i] > 122)
  410.             td->dvar[i] = '_';            /* translate periods and spaces to _ */
  411.  
  412.     strcpy(td->xvar,"X axis");
  413.     strcpy(td->yvar,"Y axis");
  414.     i = 300/xdim;
  415.     j = 300/ydim;                        /* goodly size for a default image */
  416.     if (i < j)
  417.         j = i;                            /* j is default expansion factor */
  418.     if (!j)
  419.         j = 1;                            /* if dataset is > 300, make it expansion = 1 */
  420.     td->exx = td->exy = j;
  421.     td->xsize = j*xdim;
  422.     td->ysize = j*ydim;
  423.     
  424.     SetRect(&td->viewport,-ydim/2,-ydim/2,ydim/2,ydim/2);
  425.     
  426.     td->valmax = td->valmin = 0.0;
  427.     td->angleshift = 0;
  428.     
  429.     td->refcount = 1;                    /* currently only one reference to this datawin */
  430.     td->needsave = 0;                    /* by default, needs no saving */
  431.     td->text = NULL;    
  432.     td->image = NULL;                    /* set all redirects to NULL */
  433.     td->interp = NULL;
  434.     td->polar = NULL;
  435.     td->notes = NULL;
  436.     td->content = NULL;
  437.  
  438.     return(td);
  439.  
  440. }
  441.  
  442. /*******************************************************************************/
  443. /*  clonedata
  444. *   Take an fdatawin and clones it.  Reset all of the fields
  445. *   which are tied into the record's current position after copying it.
  446. *
  447. */
  448. struct fdatawin
  449. *clonedata(tdold)
  450.     struct fdatawin *tdold;
  451.     {
  452.     struct fdatawin *td;
  453.     int xdim,ydim,len;
  454.     float *dat,*xs,*ys;
  455.     
  456. /*
  457. *  Clone the data fields from the datawin structure
  458. */
  459.     xdim = tdold->xdim;
  460.     ydim = tdold->ydim;
  461.     len = xdim*ydim*sizeof(float);
  462.     
  463.     if (NULL == (dat = (float *)NewPtr(len)))
  464.         return(NULL);        
  465.     memcpy(dat,tdold->vals,len);
  466.     
  467.     if (NULL == (xs = (float *)NewPtr(xdim*sizeof(float))))
  468.         return(NULL);
  469.     memcpy(xs,tdold->xvals,xdim*sizeof(float));
  470.  
  471.     if (NULL == (ys = (float *)NewPtr(ydim*sizeof(float))))
  472.         return(NULL);
  473.     memcpy(ys,tdold->yvals,ydim*sizeof(float));
  474.     
  475.     if (NULL == (td = (struct fdatawin *)NewPtr(sizeof(struct fdatawin))))
  476.         return(NULL);
  477.         
  478.     *td = *tdold;                /*  copy the datawin structure, every field */
  479.     
  480.     td->refcount = 1;            /* this datawin is brand new */
  481.     td->text = NULL;            /* not installed in an Mwin yet */
  482.     td->image = NULL;            /* set other redirects to NULL */
  483.     td->interp = NULL;
  484.     td->polar = NULL;
  485.     td->notes = NULL;
  486.     td->content = NULL;            /* don't copy notebook from old win */
  487.     td->fname[0] = 0;
  488.     td->needsave = 1;            /* this hasn't been saved */
  489.     
  490.     td->vals = dat;                /* install the new data copies in the struct */
  491.     td->xvals = xs;
  492.     td->yvals = ys;
  493.     
  494.     return(td);
  495. }
  496.  
  497. /*******************************************************************************/
  498. /*  extractdata
  499. *   Take an fdatawin and clone a portion of it.  
  500. *   Reset all of the fields
  501. *   which are tied into the record's current position after copying it.
  502. *
  503. */
  504. struct fdatawin
  505. *extractdata(tdold,whatr)
  506.     struct fdatawin *tdold;
  507.     Rect *whatr;
  508.     {
  509.     struct fdatawin *td;
  510.     int xdim,ydim,len,i;
  511.     float *dat,*xs,*ys;
  512. /*
  513. *  Clone the data fields from the datawin structure
  514. */
  515.     if (whatr->right > tdold->xdim)                /* safety - out of range */
  516.         whatr->right = tdold->xdim;
  517.     if (whatr->bottom > tdold->ydim)
  518.         whatr->bottom = tdold->ydim;
  519.         
  520.     xdim = whatr->right - whatr->left + 1;
  521.     ydim = whatr->bottom - whatr->top + 1;
  522.     len = xdim*sizeof(float);
  523.     
  524.     if (xdim < 2 || ydim < 2)
  525.         return(NULL);
  526.         
  527.     if (checkmem((1+xdim)*(1+ydim)*sizeof(float)+1000)) 
  528.         return(NULL);
  529.  
  530.     if (NULL == (dat = (float *)NewPtr(len*ydim)))
  531.         return(NULL);
  532.     for (i=0; i<ydim; i++)                 /* copy each line */
  533.         memcpy(dat+i*xdim,tdold->vals+(i+whatr->top)*tdold->xdim+whatr->left,len);
  534.     
  535.     if (NULL == (xs = (float *)NewPtr(xdim*sizeof(float))))
  536.         return(NULL);
  537.     memcpy(xs,tdold->xvals+whatr->left,xdim*sizeof(float));
  538.  
  539.     if (NULL == (ys = (float *)NewPtr(ydim*sizeof(float))))
  540.         return(NULL);
  541.     memcpy(ys,tdold->yvals+whatr->top,ydim*sizeof(float));
  542.     
  543.     if (NULL == (td = (struct fdatawin *)NewPtr(sizeof(struct fdatawin))))
  544.         return(NULL);
  545.         
  546.     *td = *tdold;                /*  copy the datawin structure, every field */
  547.     td->xdim = xdim;
  548.     td->ydim = ydim;            /*  The size doesn't carry */
  549.     td->xsize = xdim*td->exx;    /*  Re-do the image size by the expansion factors */
  550.     td->ysize = ydim*td->exy;
  551.     SetRect(&td->viewport,-ydim/2,-ydim/2,ydim/2,ydim/2);
  552.     
  553.     td->refcount = 1;            /* this datawin is brand new */
  554.     td->text = NULL;            /* not installed in an Mwin yet */
  555.     td->image = NULL;            /* set other redirects to NULL */
  556.     td->interp = NULL;
  557.     td->polar = NULL;
  558.     td->notes = NULL;
  559.     td->content = NULL;            /* don't copy notebook from old win */
  560.     td->fname[0] = 0;
  561.     td->needsave = 1;            /* need to save extract */
  562.     
  563.     td->vals = dat;                /* install the new data copies in the struct */
  564.     td->xvals = xs;
  565.     td->yvals = ys;
  566.     
  567.     return(td);
  568. }
  569.  
  570. /*******************************************************************************/
  571. /*  findvar
  572. *   Find the Mwin which is associated with a text record which is associated
  573. *   with data which matches a particular variable name.
  574. *
  575. *   If we don't have it, ask the user what the correct name was.
  576. */
  577. struct Mwin 
  578. *findvar(s)
  579.     char *s;
  580.     {
  581.     struct Mwin *m;
  582.     char snew[255];
  583.     int again;
  584.     
  585.     again = 1;
  586.     strcpy(snew,s);
  587.     
  588.     while (again) {
  589.         m = Mlist;
  590.         
  591.         while (m) {
  592.             if (m->wintype == FTEXT && !ncstrcmp(m->dat->dvar,snew))
  593.                 return(m);
  594.             m = m->next;
  595.         }
  596.  
  597. /*
  598. *  didn't have it, ask for correction.
  599. */
  600.         again = askvar(snew);
  601.     }
  602.     
  603.     return(NULL);    
  604. }
  605.  
  606. /*******************************************************************************/
  607. /*  ctextwin 
  608. *   Given a filled in fdatawin record, create and display the text window which
  609. *   displays that data.  Insert it into the list with all capabilities.  
  610. */
  611. ctextwin(td)
  612.     struct fdatawin *td;
  613.     {
  614.     struct Mwin *mw;
  615.     
  616.     if (!td)
  617.         return(-1);
  618.  
  619.     if (NULL == (mw = (struct Mwin *)NewPtr(sizeof(struct Mwin))))
  620.         return(-1);
  621.         
  622.     mw->wintype = FTEXT;
  623.  
  624.     if (NULL == (mw->cw = (struct ftextwin *)NewPtr(sizeof(struct ftextwin))))
  625.         return(-1);
  626.         
  627.     mw->dat = td;
  628.     td->text = mw;
  629.         
  630.     mw->cw->synchon = 0;
  631.     mw->cw->csize.h = 80;
  632.     mw->cw->csize.v = 15;
  633.     mw->cw->offt = mw->cw->offl = 0;
  634.     SetRect(&mw->cw->sel,-1,-1,-1,-1);
  635.     
  636.     mw->win = GetNewWindow(windowID, NULL, (WindowPtr) -1);
  637.     setwtitle(mw->win, mw->dat->dvar);
  638.     MoveWindow(mw->win,startwin.h,startwin.v,false);
  639.     newstartwin();
  640.     SetPort(mw->win);
  641. /*
  642. *  Load the controls (scroll bars) for the window.
  643. */
  644.     mw->cw->vbar = GetNewControl(vbarID, mw->win);
  645.     mw->cw->hbar = GetNewControl(hbarID, mw->win);
  646.     
  647. /*
  648. *  install the window in the list.
  649. */
  650.     mw->next = Mlist;
  651.     Mlist = mw;
  652.     
  653. /*
  654. *  resize to fit.
  655. */
  656.     checkfloat(mw);
  657.     ShowWindow(mw->win);                        /* make it visible */
  658.  
  659. }
  660.  
  661. /************************************************************************************/
  662. /*  checkfloat
  663. *   Resets the size of the float window and positions scroll bars so that the window
  664. *   is a multiple of the cell size.
  665. *
  666. *   Calculates and installs the count fields "csize".
  667. */
  668. checkfloat(tw)
  669.     struct Mwin *tw;
  670.     {
  671.     int i,cx,cy;
  672.     struct fdatawin *td;
  673.     struct ftextwin *tc;
  674.     Rect tr;
  675.     char s[100];
  676.     
  677.     td = tw->dat;                        /* help for later de-referencing */
  678.     tc = tw->cw;                        /* text window data */
  679.     
  680.     SetPort(tw->win);                    /* Set to the window's grafport */
  681.     TextFont(2);
  682.     TextSize(10);
  683.     
  684.     tr = tw->win->portRect;                /* Visible size of window */
  685.     tr.right -= 15;                        /* Account for scroll bars */
  686.     tr.bottom -= 15;
  687.  
  688. /*
  689. *  Calculate the correct csize by testing the sample string -10.000
  690. */
  691.     sprintf(s,td->fmt,(float)-100.0);
  692.     tc->csize.h = stringwidth(s)+8;
  693.     sprintf(s,td->labfmt,(float)-100.0);        /* try label format, too */
  694.     i = stringwidth(s)+8;
  695.     if (i > tc->csize.h)
  696.         tc->csize.h = i;                    /* use max of the values */
  697.         
  698.     sprintf(s,td->fmt,td->valmax);
  699.     if (tc->csize.h < (i= stringwidth(s)+8))    /* is maximum value larger in text form? */
  700.         tc->csize.h = i;
  701.     sprintf(s,td->fmt,td->valmin);
  702.     if (tc->csize.h < (i= stringwidth(s)+8))    /* is minimum value larger in text form? */
  703.         tc->csize.h = i;
  704.     
  705.     SetOrigin(-(tc->csize.h+1), -(tc->csize.v+1));    /* allow for row at top and side of window */
  706.     tr.right -= tc->csize.h + 1;            /* for independent vars */
  707.     tr.bottom -= tc->csize.v + 1;
  708.         
  709.     cx = (tr.right - tr.left)/tc->csize.h;    /* how many cells will fit? */
  710.     cy = (tr.bottom - tr.top)/tc->csize.v;
  711.     if (cx < 1)
  712.         cx = 1;                                /* minimum one cell visible */
  713.     if (cy < 1)
  714.         cy = 1;
  715.     
  716.     tc->ccount.h = cx;                /* set window counters to how many the window will hold */
  717.     tc->ccount.v = cy;
  718.  
  719.         SizeWindow( tw->win, (cx+1)*tc->csize.h + 15 + 1,                /* window outline */
  720.                                 (cy+1)*tc->csize.v + 15 + 1, true);
  721.         tr = tw->win->portRect;                /* Visible size of window */
  722.         tr.right -= 15;                        /* Account for scroll bars */
  723.         tr.bottom -= 15;
  724.         
  725.         MoveControl(tc->vbar, tr.right, tr.top-1);            /* scroll bars */
  726.         MoveControl(tc->hbar, tr.left-1, tr.bottom);
  727.         SizeControl(tc->vbar, 16, tr.bottom-tr.top+2);
  728.         SizeControl(tc->hbar, tr.right-tr.left+2, 16);
  729.     
  730.     tc->forcedraw = 0;
  731. }
  732.  
  733. /************************************************************************************/
  734. /*  drawfloat
  735. *  Draws the given window structure from scratch.
  736. *  Leaves the grafport set to the window requested.
  737. *  dh,dv is a special mod - if they are non-zero, then we know that the window can
  738. *  be scrolled to make the new display.
  739. */
  740. drawfloat(tw,dh,dv)
  741.     struct Mwin *tw;
  742.     int dh,dv;
  743.     {
  744.     int i,j,
  745.     si,sj,                            /* start limit for the loop */
  746.     cx,cy,                            /* limits of loop to draw in main window */
  747.     skipcnt,
  748.     widex,widey,                    /* width of one item window */
  749.     a,b;
  750.     register float *f;
  751.     Rect tr,etr;
  752.     char s[100];
  753.     struct fdatawin *td;
  754.     struct ftextwin *tc;
  755.  
  756.     td = tw->dat;                    /* help for later de-referencing */
  757.     tc = tw->cw;                    /* text window data */
  758.     
  759.     SetPort(tw->win);                /* Set to the window's grafport */
  760.     
  761.     tr = tw->win->portRect;
  762.     tr.bottom -= 15;
  763.     tr.right -= 15;
  764.     
  765.     cx = tc->ccount.h;                /* set window counters to how many the window will hold */
  766.     cy = tc->ccount.v;
  767.     a = b = 0;
  768.  
  769.     if (tc->offt + cy > td->ydim) {    /* portion off of bottom of array */
  770.         cy = td->ydim - tc->offt;
  771.         a = 1;
  772.     }
  773.     if (tc->offl + cx > td->xdim) {    /* portion off of the right of array */
  774.         cx = td->xdim - tc->offl;
  775.         b = 1;
  776.     }
  777.         
  778.     widex = tc->csize.h;            /* set cell sizes where we can get them easy */
  779.     widey = tc->csize.v;
  780. /*
  781. *  draw dividers for row/col labels
  782. */
  783.     PenMode(srcCopy);
  784.     MoveTo(-widex-1,-1);
  785.     LineTo(tr.right,-1);
  786.     MoveTo(-1,-widey-1);
  787.     LineTo(-1,tr.bottom);
  788. /*
  789. *   Label the rows and columns with the xs and ys stored in the data structure
  790. */
  791.     if (!dv) {
  792.         SetRect(&etr, 0, -widey-1, tr.right, -2 );
  793.         EraseRect(&etr);
  794.         f = td->xvals + tc->offl;
  795.         for (i=0; i<cx; i++) {
  796.             sprintf(s,td->labfmt,*f++);
  797.             MoveTo(i*widex+2,-4);
  798.             drawstring(s);                /* draw it */
  799.         }
  800.     }
  801.     
  802.     if (!dh) {
  803.         SetRect(&etr, -widex-1, 0, -2, tr.bottom );
  804.         EraseRect(&etr);
  805.         f = td->yvals + tc->offt;
  806.         for (i=0; i<cy; i++) {
  807.             sprintf(s,td->labfmt,*f++);
  808.             MoveTo(-widex+2,(i+1)*widey-4);
  809.             drawstring(s);                /* draw it */
  810.         }
  811.     }
  812.  
  813. /*
  814. *  Draw in the data inside the window.  First check to see if we can scroll to save work.
  815. */
  816.     si = sj = 0;
  817.     
  818.     if (dh > cx || -dh > cx || dv > cy || -dv > cy)
  819.         dh = dv = 0;
  820.     
  821.     if (dh || dv) {                        /* we can scroll */
  822.  
  823.         SetRect(&etr, 0, 0, widex*tc->ccount.h, widey*tc->ccount.v );
  824.         
  825.         if (dh < 0) 
  826.             cx = sj - dh;
  827.         if (dh > 0) 
  828.             sj = cx - dh;                /* change drawing region */
  829.         if (dv < 0) 
  830.             cy = si - dv;
  831.         if (dv > 0) 
  832.             si = cy - dv;
  833.         
  834.         ScrollRect(&etr, -dh*widex, -dv*widey, Urgn);
  835.         inscrfloat(tw);                                /* invalidate bars, so they will re-draw */
  836.         
  837.         if ((dv > 0 && a) || (dh > 0 && b))            /* check for condition where drawing is not needed */
  838.             return;
  839.  
  840.     }
  841.     else {        
  842.         tr = tw->win->portRect;
  843.         tr.top = 0;
  844.         tr.left = 0;
  845.         tr.bottom -= 15;
  846.         tr.right -= 15;
  847.         EraseRect(&tr);                                /* Clear stuff in window */
  848.     }
  849.  
  850.  
  851.     PenMode(srcCopy);
  852.     f = td->vals + (tc->offt + si)*td->xdim + 
  853.         tc->offl + sj;                                /* start of data segment */
  854.  
  855.     skipcnt = td->xdim - cx + sj;                    /* how many to skip each time */
  856.     
  857.     for (i=si; i<cy; i++) {
  858.         for (j=sj; j<cx; j++) {
  859.             sprintf(s,td->fmt,*f++);                /* get text representation of float # */
  860. /*
  861. *  position the text inside the cell.  Four pixels up from the bottom of the cell.
  862. *  Two pixels over from the side of the cell.
  863. */
  864.             MoveTo(j*widex+2,(i+1)*widey-4);
  865.             drawstring(s);
  866.             a = tc->offt + i;
  867.             b = tc->offl + j;
  868.             if (a >= tc->sel.top && a <= tc->sel.bottom &&
  869.                 b >= tc->sel.left && b <= tc->sel.right) 
  870.                 invertfloat(tw,b,a);
  871.             
  872.         }
  873.         
  874.         f += skipcnt;
  875.     }
  876.     
  877. }
  878.  
  879. /************************************************************************************/
  880. /*  invertfloat
  881. *   Take a cell in the visible array and invert it.  The cell is in data coordinates.
  882. */
  883. invertfloat(tw,x,y)
  884.     struct Mwin *tw;
  885.     int x,y;
  886.     {
  887.     Rect tr;
  888.     int i,j,widex,widey;
  889.     struct fdatawin *td;
  890.     struct ftextwin *tc;
  891.     
  892.     td = tw->dat;                    /* help for later de-referencing */
  893.     tc = tw->cw;                    /* text window data */
  894.     
  895.     if (x < tc->offl || y < tc->offt ||
  896.         x >= tc->offl + tc->ccount.h ||
  897.         y >= tc->offt + tc->ccount.v ||
  898.         x >= td->xdim || y >= td->ydim)
  899.         return;
  900.         
  901.     j = x - tc->offl;                /* put into screen coordinates */
  902.     i = y - tc->offt;
  903.     
  904.     widex = tc->csize.h;            /* stored size of each cell */
  905.     widey = tc->csize.v;
  906.     
  907.     tr.top = i*widey;
  908.     tr.bottom = (i+1)*widey;
  909.     tr.left = j*widex;
  910.     tr.right = (j+1)*widex;
  911.     InvertRect(&tr);
  912.  
  913. }
  914.  
  915. /************************************************************************************/
  916. /* controlfloat
  917. *  Draw the controls according to the current window active region setting.
  918. */
  919. controlfloat(tw)
  920.     struct Mwin *tw;
  921.     {
  922.  
  923.     if (tw->dat->ydim > 1) {
  924.         SetCtlValue(tw->cw->vbar,1000*tw->cw->offt/(tw->dat->ydim-1));
  925.         SetCtlValue(tw->cw->hbar,1000*tw->cw->offl/(tw->dat->xdim-1));
  926.     }
  927.     
  928.     DrawControls(tw->win);
  929.     DrawGrowIcon(tw->win);
  930.  
  931. }
  932.  
  933. /************************************************************************************/
  934. /* copyfloat
  935. *  Copy the selected data into the Scrap Manager for pasting into other programs.
  936. */
  937. copyfloat(tw)
  938.     struct Mwin *tw;
  939.     {
  940.     int len,datsize,i,j,cx,cy,skipcnt;
  941.     char *data,*p;
  942.     register float *f;
  943.     char s[100];
  944.     struct fdatawin *td;
  945.     struct ftextwin *tc;
  946.     
  947.     td = tw->dat;                    /* help for later de-referencing */
  948.     tc = tw->cw;                    /* text window data */
  949.  
  950.     sprintf(s,td->fmt,(float)0.0);
  951.     len = strlen(s);
  952.  
  953.     cx = tc->sel.right-tc->sel.left+1;    
  954.     cy = tc->sel.bottom-tc->sel.top+1;
  955.     
  956.     datsize = (len+1)*cy*cx;            /* total data area size */
  957.     if (NULL == (p = data = (char *)NewPtr(datsize+10)))
  958.         return(-1);
  959.     
  960.     f = td->vals + tc->sel.top*td->xdim + tc->sel.left;    /* start of data segment */
  961.     
  962.     skipcnt = td->xdim - cx;            /* how many to skip each time */
  963.     
  964.     for (i=0; i<cy; i++) {
  965.         for (j=0; j<cx; j++) {
  966.             sprintf(p,td->fmt,*f++);    /* get text representation of float # */
  967.             p += len;
  968.             *p++ = '\t';                /* tab delimiters */
  969.         }
  970.         *(p-1) = '\n';                    /* newline at end of line */
  971.         f += skipcnt;
  972.     }
  973.     
  974. /*
  975. *  Scrap calls.
  976. */
  977.     ZeroScrap();
  978.     if (noErr != (i = (int)PutScrap(datsize,'TEXT',data))) {        /* put it there */
  979.         if (i == -108)
  980.             nomem();                    /* out of memory */
  981.         ZeroScrap();                    /* clear it, no good */
  982.     }
  983.     
  984.     DisposPtr(data);                            /* don't need to keep memory now */
  985. }
  986.  
  987. /************************************************************************************/
  988. /*  inscrfloat
  989. *      Invalidate the current scroll bars so that they will be re-drawn.
  990. */
  991. inscrfloat(tw)
  992.     struct Mwin *tw;
  993.     {
  994.     Rect tr;
  995. /*
  996. *  Force a re-draw of scrollbars and grow icon.  
  997. *
  998. */
  999.     tr = (*tw->cw->vbar)->contrlRect;    /* vertical scroll bar rect */
  1000.     tr.bottom += 20;                    /* include grow icon */
  1001.     InvalRect(&tr);                        /* invalidate this region */
  1002.     
  1003.     tr = (*tw->cw->hbar)->contrlRect;    /* same for horizontal */
  1004.     InvalRect(&tr);
  1005.  
  1006. }
  1007.  
  1008.  
  1009. /************************************************************************************/
  1010. /*  growfloat
  1011. *   In a floating point window, redraw it according to a grow operation.
  1012. */
  1013. growfloat(tw, where)
  1014.     Point *where;
  1015.     struct Mwin *tw;
  1016.     {
  1017.     int newsize;
  1018.             
  1019.     SetPort(tw->win);
  1020.     
  1021.     newsize = growwindow( tw->win, where, &qd.screenBits.bounds);
  1022.     
  1023.     if (!newsize)
  1024.         return(1);
  1025.         
  1026.     SizeWindow( tw->win, LoWord(newsize), HiWord(newsize), true);
  1027.  
  1028.     inscrfloat(tw);                        /* invalidate current scroll bar regions */
  1029. /*
  1030. *  Now that the old scroll bars have been invalidated, check the window size and
  1031. *  control positions.  Cause them to move to make the window a multiple of the
  1032. *  cell size.  Will invalidate all regions which need to be re-drawn.
  1033. */
  1034.     checkfloat(tw);                        
  1035.     
  1036.     return(1);
  1037. }
  1038.  
  1039. /***************************************************************************************/
  1040. /*  setfloat
  1041. *  Sets the current selection rectangle in the given text window.
  1042. *  Invalidates the window so that it will re-draw.
  1043. */
  1044. setfloat(tw,sr)
  1045.     struct Mwin *tw;
  1046.     Rect *sr;
  1047.     {
  1048.     struct ftextwin *tc;
  1049.     
  1050.     if (tw->wintype != FTEXT)
  1051.         return;
  1052.         
  1053.     if (sr->right >= tw->dat->xdim)                /* safety check of bounds */
  1054.         sr->right = tw->dat->xdim-1;
  1055.     if (sr->bottom >= tw->dat->ydim)
  1056.         sr->bottom = tw->dat->ydim-1;
  1057.  
  1058.     tc = tw->cw;
  1059.     tc->sel = *sr;                                /* set selection rectangle */
  1060.     
  1061.     tc->offl = sr->left - ((tc->ccount.h - (sr->right-sr->left))>>1);        /* center it */
  1062.     if (tc->offl < 0)
  1063.         tc->offl = 0;
  1064.     tc->offt = sr->top - ((tc->ccount.v - (sr->bottom-sr->top))>>1);
  1065.     if (tc->offt < 0)
  1066.         tc->offt = 0;
  1067.  
  1068.     SetPort(tw->win);                        /* refer to the text window */
  1069.     InvalRect(&tw->win->portRect);
  1070.  
  1071.     
  1072. }
  1073.  
  1074. /***************************************************************************************/
  1075. /*  loseit
  1076. *   Get rid of all windows which are associated with a particular dataset.
  1077. */
  1078. loseit(tw)
  1079.     struct Mwin *tw;
  1080. {
  1081.     struct fdatawin *td;
  1082.     struct Mwin *mw;
  1083.     
  1084.     if (!tw || !(td = tw->dat))
  1085.         return;
  1086.     
  1087.     mw = Mlist;
  1088.     while (mw) {
  1089.         if (mw->dat == td) {            /* if it has anything to do with same data */
  1090.         
  1091.             switch (mw->wintype) {
  1092.             case FTEXT:
  1093.                 if (checksave(mw))        /* save file first? */
  1094.                     return;                /* didn't want to go away */
  1095.                 losefloat(mw);
  1096.                 break;
  1097.             case FIMG:
  1098.                 loseimage(mw);
  1099.                 break;
  1100.             case FBI:
  1101.                 loseinterp(mw);
  1102.                 break;
  1103.             case FPOL:
  1104.                 losepolar(mw);
  1105.                 break;
  1106.             case FNOTES:
  1107.                 losenotes(mw);
  1108.                 break;
  1109.             }
  1110.         }
  1111.         
  1112.         mw = mw->next;
  1113.     }
  1114.                 
  1115. }
  1116.  
  1117. /***************************************************************************************/
  1118. /*  losefloat
  1119. *   Take a text window out of the list and get rid of all links.
  1120. */
  1121. losefloat(tw)
  1122.     struct Mwin *tw;
  1123. {
  1124.     
  1125. /*
  1126. *   Remove the back pointer from the dataset
  1127. */
  1128.     if (tw->dat->text == tw)        /* this should ALWAYS be true */
  1129.         tw->dat->text = NULL;
  1130.  
  1131. /*
  1132. *  losedat only takes away this parition's reference to the data.  If this is
  1133. *  the last reference, then the memory will be released.
  1134. */
  1135.     losedat(tw->dat);
  1136.  
  1137.     DisposeControl(tw->cw->vbar);    /* scroll bars */
  1138.     DisposeControl(tw->cw->hbar);
  1139.     DisposPtr((Ptr) tw->cw);
  1140.  
  1141.     rmwin(tw);                        /* take window out of list */
  1142.     
  1143.     DisposeWindow(tw->win);
  1144.     DisposPtr((Ptr) tw);
  1145.                 
  1146. }
  1147.  
  1148. /*******************************************************************************/
  1149. /*  openfloat
  1150. *  Open a new data file, use the Standard File and then call getdf to establish
  1151. *  the new window(s).  getdf will load all of the correct contents into the right
  1152. *  places.
  1153. */
  1154. openfloat(tw)
  1155.     struct Mwin *tw;
  1156.     {
  1157.      SFReply reply;
  1158.      Point wh;
  1159.     
  1160.     wh.h = wh.v = 50;
  1161.     /* tlst[0] = mytype; */
  1162.     sfgetfile(&wh, "Open HDF data file", nil, -1, nil,
  1163.             nil, &reply);
  1164.     if (reply.good) {
  1165.         p2cstr(reply.fName);
  1166.         setvol(NULL, reply.vRefNum);            /* set to this volume (dir) */
  1167.         getdf(reply.fName);                        /* load this file */
  1168.  
  1169.     }
  1170.  
  1171. }
  1172.  
  1173. /*******************************************************************************/
  1174. /*  loadtext
  1175. *  Open a new data file, use the Standard File and then call gettext to establish
  1176. *  the new window.
  1177. */
  1178. loadtext(tw)
  1179.     struct Mwin *tw;
  1180.     {
  1181.      SFReply reply;
  1182.      SFTypeList tlst;
  1183.      Point wh;
  1184.      int ret;
  1185.     
  1186.     wh.h = wh.v = 50;
  1187.     tlst[0] = 'TEXT';
  1188.     sfgetfile(&wh, "Open Text data file", nil, 1, tlst,
  1189.             nil, &reply);
  1190.     if (reply.good) {
  1191.         p2cstr(reply.fName);
  1192.         setvol(NULL, reply.vRefNum);            /* set to this volume (dir) */
  1193.         ret = gettext(reply.fName);                /* load this file */
  1194.         
  1195.         if (ret < 0) {
  1196.             paramtext(reply.fName,"","","");
  1197.             StopAlert(1004, nil);
  1198.             return(-1);
  1199.         }
  1200.     
  1201.     }
  1202.  
  1203. }
  1204.  
  1205. /*******************************************************************************/
  1206. /*  doatt
  1207. *   put up the attributes dialog box and process all of the options.
  1208. */
  1209. # define attrDLOG  129
  1210.  
  1211. # define afname 4
  1212. # define aok    1
  1213. # define acancel 3
  1214. # define adepend    5
  1215. # define axax        6
  1216. # define ayax        7
  1217. # define afmt        8
  1218. # define amax        9
  1219. # define amin        10
  1220. # define acmin        11
  1221. # define acmax        12
  1222. # define adh        13
  1223. # define alfmt      15
  1224. # define adv        2
  1225. # define aoutl      16
  1226. # define acalc        17
  1227.  
  1228.  
  1229. extern pascal void OutlineItem();
  1230.     
  1231. doatt(tw)
  1232.     struct Mwin *tw;
  1233. {
  1234.     GrafPtr        savePort;
  1235.     DialogPtr    theDialog;
  1236.     short        itemType;
  1237.     Handle        itemHdl;
  1238.     Rect        itemRect;
  1239.     short        itemHit;
  1240.     char s[257];
  1241.     struct fdatawin *td;
  1242.     float tf;
  1243.             
  1244.     td = tw->dat;
  1245.     
  1246.     GetPort(&savePort);
  1247.     theDialog = GetNewDialog(attrDLOG, nil, (WindowPtr) -1);
  1248.     SetPort(theDialog);
  1249.  
  1250.     UItemAssign( theDialog, aoutl, OutlineItem);
  1251. /*
  1252. *  set previous values into the dialog
  1253. */
  1254.     GetDItem(theDialog, afname, &itemType, &itemHdl, &itemRect);
  1255.     setitext(itemHdl, td->fname);
  1256.     GetDItem(theDialog, adepend, &itemType, &itemHdl, &itemRect);
  1257.     setitext(itemHdl, td->dvar);
  1258.     GetDItem(theDialog, axax, &itemType, &itemHdl, &itemRect);
  1259.     setitext(itemHdl, td->xvar);
  1260.     GetDItem(theDialog, ayax, &itemType, &itemHdl, &itemRect);
  1261.     setitext(itemHdl, td->yvar);
  1262.     GetDItem(theDialog, amax, &itemType, &itemHdl, &itemRect);
  1263.     sprintf(s,td->fmt,td->valmax);
  1264.     setitext(itemHdl, s);
  1265.     GetDItem(theDialog, amin, &itemType, &itemHdl, &itemRect);
  1266.     sprintf(s,td->fmt,td->valmin);
  1267.     setitext(itemHdl, s);
  1268.     GetDItem(theDialog, afmt, &itemType, &itemHdl, &itemRect);
  1269.     c2ftn(td->fmt,s,"E11.4");
  1270.     setitext(itemHdl, s);
  1271.     GetDItem(theDialog, alfmt, &itemType, &itemHdl, &itemRect);
  1272.     c2ftn(td->labfmt,s,"F5.1");
  1273.     setitext(itemHdl, s);
  1274.     GetDItem(theDialog, acmin, &itemType, &itemHdl, &itemRect);
  1275.     sprintf(s,"%d",td->cmin);
  1276.     setitext(itemHdl, s);
  1277.     GetDItem(theDialog, acmax, &itemType, &itemHdl, &itemRect);
  1278.     sprintf(s,"%d",td->cmax);
  1279.     setitext(itemHdl, s);
  1280.     GetDItem(theDialog, adh, &itemType, &itemHdl, &itemRect);
  1281.     sprintf(s,"%d",td->ydim);
  1282.     setitext(itemHdl, s);
  1283.     GetDItem(theDialog, adv, &itemType, &itemHdl, &itemRect);
  1284.     sprintf(s,"%d",td->xdim);
  1285.     setitext(itemHdl, s);
  1286.     
  1287.     SelIText(theDialog, adepend, 0,32767);
  1288.  
  1289.     do {
  1290.         ModalDialog(nil, &itemHit);
  1291.         
  1292.         switch (itemHit) {
  1293.         case acancel:
  1294.             SetPort(savePort);
  1295.             DisposDialog(theDialog);
  1296.             return;
  1297.         case acalc:
  1298.             maxmin( td->vals, td->xdim, td->ydim, &td->valmax, &td->valmin,
  1299.                 0,0,td->ydim, td->xdim);
  1300.             GetDItem(theDialog, amax, &itemType, &itemHdl, &itemRect);
  1301.             sprintf(s,td->fmt,td->valmax);
  1302.             setitext(itemHdl, s);
  1303.             GetDItem(theDialog, amin, &itemType, &itemHdl, &itemRect);
  1304.             sprintf(s,td->fmt,td->valmin);
  1305.             setitext(itemHdl, s);
  1306.             break;
  1307.         default:
  1308.             break;
  1309.         }
  1310.     } while (itemHit != aok);
  1311.     
  1312.  
  1313.     GetDItem(theDialog, afmt, &itemType, &itemHdl, &itemRect);
  1314.     getitext(itemHdl, s);
  1315.     ftn2c(s,td->fmt,"%11.4e");
  1316.     GetDItem(theDialog, alfmt, &itemType, &itemHdl, &itemRect);
  1317.     getitext(itemHdl, s);
  1318.     ftn2c(s,td->labfmt,"%5.1f");
  1319.     
  1320.     GetDItem(theDialog, acmin, &itemType, &itemHdl, &itemRect);
  1321.     getitext(itemHdl, s);
  1322.     td->cmin = atoi(s);
  1323.     if (td->cmin < CLORLOWER) td->cmin = CLORLOWER;
  1324.     if (td->cmin > CLORHIGHER)    td->cmin = CLORHIGHER;
  1325.     GetDItem(theDialog, acmax, &itemType, &itemHdl, &itemRect);
  1326.     getitext(itemHdl, s);
  1327.     td->cmax = atoi(s);
  1328.     if (td->cmax < CLORLOWER) td->cmax = CLORLOWER;
  1329.     if (td->cmax < td->cmin)
  1330.         td->cmax = td->cmin;
  1331.     if (td->cmax > CLORHIGHER)    td->cmax = CLORHIGHER;
  1332.     
  1333.     GetDItem(theDialog, amax, &itemType, &itemHdl, &itemRect);
  1334.     getitext(itemHdl, s);
  1335.     tf = atof(s);                    /* set new max value */
  1336.     if (tf > -1e30 && tf < 1e30)
  1337.         td->valmax = tf;
  1338.     GetDItem(theDialog, amin, &itemType, &itemHdl, &itemRect);
  1339.     getitext(itemHdl, s);
  1340.     tf = atof(s);                    /* set new min value */
  1341.     if (tf > -1e30 && tf < 1e30)
  1342.         td->valmin = tf;
  1343.     
  1344.     GetDItem(theDialog, adepend, &itemType, &itemHdl, &itemRect);
  1345.     getitext(itemHdl, s);
  1346. /*
  1347. *  if the variable name has changed, we must change all of the corresponding
  1348. *  window titles and the stored variable name.
  1349. */
  1350.     if (strcmp(td->dvar,s)) {
  1351.         if (td->text)
  1352.             setwtitle(td->text->win,s);            /* set window to this title */
  1353.         if (td->polar)
  1354.             setwtitle(td->polar->win,s);        /* set window to this title */
  1355.         if (td->image)
  1356.             setwtitle(td->image->win,s);        /* set window to this title */
  1357.         if (td->interp)
  1358.             setwtitle(td->interp->win,s);        /* set window to this title */
  1359.         if (td->notes)
  1360.             setwtitle(td->notes->win,s);        /* set window to this title */
  1361.         strncpy(td->dvar,s,19);
  1362.     }
  1363.     GetDItem(theDialog, axax, &itemType, &itemHdl, &itemRect);
  1364.     getitext(itemHdl, s);
  1365.     strncpy(td->xvar,s,19);
  1366.     GetDItem(theDialog, ayax, &itemType, &itemHdl, &itemRect);
  1367.     getitext(itemHdl, s);
  1368.     strncpy(td->yvar,s,19);
  1369.     
  1370.     if (td->text) {
  1371.         checkfloat(td->text);        /* reset float window with new parms */
  1372.         SetPort(td->text->win);
  1373.         InvalRect(&td->text->win->portRect);    /* window will re-draw in entirety */
  1374.         SetPort(savePort);
  1375.     }
  1376.  
  1377.     DisposDialog(theDialog);
  1378.  
  1379.     return;
  1380. }
  1381.  
  1382. /************************************************************************************/
  1383. /*  c2ftn, ftn2c
  1384. *   Translate from one number format string to another.
  1385. *   Fill in the program default when the string is invalid.
  1386. */
  1387. c2ftn(cs,fs,def)
  1388.     char *cs,*fs,*def;
  1389.     {
  1390.     int wide,prec;
  1391.     char fc;
  1392.  
  1393.     if (3 != sscanf(cs,"%%%d.%d%c",&wide,&prec,&fc)) {
  1394.         strcpy(fs,def);
  1395.         return;
  1396.     }
  1397.     
  1398.     sprintf(fs,"%c%d.%d",toupper(fc),wide,prec);
  1399.     
  1400. }
  1401.  
  1402. ftn2c(fs,cs,def)
  1403.     char *fs,*cs,*def;
  1404.     {
  1405.     int wide,prec;
  1406.     char fc;
  1407.  
  1408.     if (tolower(*fs) == 'i') {
  1409.         if (1 != sscanf(&fs[1],"%d",&wide)) {
  1410.             strcpy(cs,def);
  1411.             return;
  1412.         }
  1413.         fc = 'f';
  1414.         prec = 0;
  1415.     }
  1416.     else {
  1417.         if (3 != sscanf(fs,"%c%d.%d",&fc,&wide,&prec)) {
  1418.             strcpy(cs,def);
  1419.             return;
  1420.         }
  1421.     }
  1422.     
  1423.     sprintf(cs,"%%%d.%d%c",wide,prec,tolower(fc));
  1424.  
  1425. }
  1426.  
  1427. /************************************************************************************/
  1428. struct Mwin *targ;
  1429.  
  1430. pascal void mybits(srcBits, srcRect,dstRect, mode, maskRgn)
  1431.     PixMapPtr srcBits;
  1432.     Rect *srcRect,*dstRect;
  1433.     short mode;
  1434.     RgnHandle maskRgn;
  1435. {
  1436.     register int i,j,trans,lim;
  1437.     char *p;
  1438.  
  1439.     trans = 1;
  1440.     if ((*srcBits->pmTable)->ctFlags & 0x8000)
  1441.         trans = 0;
  1442.     lim = (*srcBits->pmTable)->ctSize;            /* number of entries in color table */
  1443.     if (lim > 255)
  1444.         lim = 255;
  1445.     p = rgbsave;
  1446.     for (i=0; i<lim; i++) {                        /* convert color table to our storage format */
  1447.         j = i;
  1448.         if (trans) {
  1449.             j = (*srcBits->pmTable)->ctTable[i].value;
  1450.             if (j > 255 || j < 0)
  1451.                 j = 0;
  1452.         }
  1453.         *p++ = (*srcBits->pmTable)->ctTable[j].rgb.red >> 8;
  1454.         *p++ = (*srcBits->pmTable)->ctTable[j].rgb.green >> 8;
  1455.         *p++ = (*srcBits->pmTable)->ctTable[j].rgb.blue >> 8;
  1456.     }
  1457.     setpal(targ,rgbsave);                        /* install color table for use */
  1458.  
  1459.     StdBits((BitMap *) srcBits,                             /* then call it */
  1460.             srcRect, dstRect, mode, maskRgn); 
  1461.  
  1462. }
  1463.  
  1464. /************************************************************************************/
  1465. /*  dopaste
  1466. *  create a new dataset if the paste data is usable.
  1467. */
  1468. dopaste(tw)
  1469.     struct Mwin *tw;
  1470.     {
  1471.     struct Mwin *tempw;
  1472.     register int i,j;
  1473.     int wide,tall,lim;
  1474.     register float *f;
  1475.     register unsigned char *p;
  1476.     unsigned char *pstart;
  1477.     struct fdatawin *td;
  1478.     struct fimgwin *ti;
  1479.     PicHandle pich;
  1480.     int picsize;
  1481.     Rect pframe;
  1482.     CQDProcs myprocs;
  1483.     
  1484.     LoadScrap();
  1485.  
  1486.     if (clutpaste(tw))            /* check for color table pasting */
  1487.         return(0);
  1488. /*
  1489. *  Check for PICT waiting to be pasted.  We will be creating two windows to hold the
  1490. *  data from this PICT.
  1491. */
  1492.     pich = (PicHandle)NewHandle(0);
  1493.     picsize = GetScrap( (Handle) pich, 'PICT', &lim);
  1494.     if (picsize <= 0)
  1495.         return(textpaste());
  1496.         
  1497.     pframe = (*pich)->picFrame;                /* get dimensions */
  1498.     wide = pframe.right - pframe.left;
  1499.     tall = pframe.bottom - pframe.top;
  1500.     pframe.top = 0;
  1501.     pframe.left = 0;
  1502.     pframe.right = wide;
  1503.     pframe.bottom = tall;
  1504.     
  1505. /*
  1506. *  Is the image too small in either direction to give it its own window?
  1507. *  Are we going to have enough memory to do this?
  1508. *  5 bytes = 4 bytes for each data point in floating point + 1 byte for image, each point.
  1509. */
  1510.  
  1511.     if (wide < 30 ||
  1512.         tall < 30 ||
  1513.         checkmem((wide+1)*(tall+1)*5+1000)) {
  1514.         DisposHandle((Handle) pich);
  1515.         return(-1);
  1516.     }
  1517.  
  1518.     if (NULL == (td = newdatawin("Untitled",wide,tall))) {
  1519.         DisposHandle((Handle) pich);
  1520.         return(-1);
  1521.     }
  1522.     
  1523.     strcpy(td->fname,"Untitled");
  1524.     strcpy(td->fmt,"%5.0f");
  1525.     td->needsave = 1;
  1526.  
  1527.     tempw = (struct Mwin *)NewPtr(sizeof(struct Mwin));
  1528.         
  1529.     tempw->dat = td;                /* point to same dataset */
  1530.     tempw->dat->refcount++;            /* increase refcount bookkeeping */
  1531.     tempw->iw = (struct fimgwin *)NewPtr(sizeof(struct fimgwin));
  1532.     
  1533.     tw = tempw;                        /* move to this element of list */
  1534.     
  1535.     td->image = tw;                    /* back pointer for text references */
  1536.     tw->wintype = FIMG;                /* indicate the image type flag */
  1537.     
  1538.     ti = tw->iw;                    /* image window stuff */
  1539.  
  1540.     SetRect(&ti->xr,-11,-11,-11,-11);                /* flag that box isn't set yet */
  1541.     ti->exx = 1;
  1542.     ti->exy = 1;
  1543.  
  1544.     tw->pref = pframe;                /* handles odd width */
  1545.  
  1546.     if ( 0 > blankimg(tw,&tw->vdev, wide, tall, wide, tall))
  1547.         return;                        /* set up window stuff */
  1548.  
  1549. /*
  1550. *  Replace the standard copybits call with my own.  During DrawPicture, mine will be called.
  1551. */
  1552.     SetStdCProcs(&myprocs);
  1553.     tw->vdev.vport.grafProcs = (CQDProcsPtr) &myprocs;
  1554.     myprocs.bitsProc = (Ptr)mybits;
  1555.     targ = tw;
  1556. /*
  1557. *  Install the image which we got from the clipboard.
  1558. */
  1559.      SetVDevice(&tw->vdev);
  1560.     
  1561.     DrawPicture(pich, &pframe);
  1562.     
  1563.     UnsetVDevice(&tw->vdev);
  1564.  
  1565. /*
  1566. *  Different from makeimage, this time we convert from image back to the floating
  1567. *  point instead of the other way around.
  1568. */
  1569.     f = td->vals;                            /* floating pt data */
  1570.     p = pstart = tw->vdev.bp;                /* data space available */
  1571.  
  1572.     for (i=0; i<tall; i++) {
  1573.         for (j=0; j<wide; j++)
  1574.             *f++ = *p++;                    /* compiler converts datatypes for us */
  1575.         if (wide & 1)
  1576.             p++;
  1577.     }
  1578.  
  1579.     f = td->yvals;
  1580.     for (i=0; i<tall ; i++)
  1581.         *f++ = (float)i;                    /* defaults if they are not there */
  1582.  
  1583.     f = td->xvals;
  1584.     for (i=0; i<wide ; i++)
  1585.         *f++ = (float)i;                    /* defaults if they are not there */
  1586.  
  1587.  
  1588. /*
  1589. *  If we get this far, then we assume things are ok and we start 'er up.
  1590. */
  1591.     maxmin( td->vals, wide, tall,
  1592.             &td->valmax, &td->valmin, 0,0, tall, wide);
  1593.  
  1594.     ctextwin(td);
  1595.     
  1596.     td->cmin = td->valmin;            /* assign color range from image as pasted */
  1597.     td->cmax = td->valmax;
  1598.  
  1599.     tw->next = Mlist;                /* install in list */
  1600.     Mlist = tw;
  1601.     
  1602.     DisposHandle((Handle) pich);                /* don't need pic memory anymore */
  1603.     return(0);
  1604.  
  1605. }
  1606.  
  1607. /************************************************************************************/
  1608. /*  clutpaste
  1609. *  create a new dataset if the paste data is usable.
  1610. */
  1611. clutpaste(tw)
  1612.     struct Mwin *tw;
  1613. {
  1614.     register int i,j;
  1615.     int lim;
  1616.     register unsigned char *p;
  1617.     CTabHandle cth;
  1618.     int csize;
  1619.     
  1620. /*
  1621. *  Check for CLUT waiting to be pasted. 
  1622. */
  1623.     cth = (CTabHandle)NewHandle(0);
  1624.     csize = GetScrap( (Handle) cth, 'clut', &lim);
  1625.     if (csize <= 0)
  1626.         return(0);
  1627.         
  1628.     HLock( (Handle) cth);
  1629.     lim = (*cth)->ctSize;                        /* number of entries in color table */
  1630.     if (lim > 255)
  1631.         lim = 255;
  1632.  
  1633.     p = rgbsave;
  1634.     for (i=0; i<lim; i++) {                        /* convert color table to our storage format */
  1635.         j = i;
  1636.         j = (*cth)->ctTable[i].value;
  1637.         if (j > 255 || j < 0)
  1638.             j = 0;
  1639.         *p++ = (*cth)->ctTable[j].rgb.red >> 8;
  1640.         *p++ = (*cth)->ctTable[j].rgb.green >> 8;
  1641.         *p++ = (*cth)->ctTable[j].rgb.blue >> 8;
  1642.     }
  1643.     
  1644.     HUnlock( (Handle) cth);
  1645.     DisposHandle((Handle) cth);
  1646.     
  1647.     setpal(tw,rgbsave);                            /* install color table for use */
  1648.     
  1649.     return(1);
  1650. }
  1651.  
  1652. /************************************************************************************/
  1653. /*  textpaste
  1654. *  create a new dataset if the paste data is usable.
  1655. */
  1656. textpaste()
  1657.     {
  1658.     struct Mwin *tempw,*tw;
  1659.     register int i,j;
  1660.     int wide,tall,lim;
  1661.     register float *f;
  1662.     register unsigned char *p;
  1663.     unsigned char *pstart;
  1664.     struct fdatawin *td;
  1665.     Handle txth;
  1666.     int tsize;
  1667.     
  1668. /*
  1669. *  Check for TEXT waiting to be pasted.  We will be creating two windows to hold the
  1670. *  data from this PICT.
  1671. */
  1672.     txth = (Handle)NewHandle(0);
  1673.     tsize = GetScrap( txth, 'TEXT', &lim);
  1674.     if (tsize <= 0)
  1675.         return(-1);
  1676.     
  1677.     HLock(txth);
  1678.     pstart = p = *txth;                                /* start of text record */
  1679.     tall = 0;
  1680.     wide = 0;
  1681.     j = 0;
  1682.     
  1683.     
  1684. /*
  1685. *  Count the number per line and the number of lines.
  1686. */
  1687.     
  1688.     for (i=0; i<tsize; ) {
  1689.         while (i < tsize && (*p == ' ' || *p == 9)) {  /* skip white space */
  1690.             p++; i++;
  1691.         }
  1692.         j++;
  1693.         while (i < tsize && (*p > ' '))    {    /* skip the number */
  1694.             p++; i++;
  1695.         }
  1696.         
  1697.         if (*p == 13) {                        /* if at EOL, keep track */
  1698.             /* printf("i: %d, lim: %d, tall: %d\n",i,tsize,tall); */
  1699.             if (j > 1)                        /* don't count lines with one or fewer numbers */
  1700.                 tall++;
  1701.             if (j > wide)
  1702.                 wide = j;
  1703.             j = 0;
  1704.             p++;                            /* get past EOL */
  1705.             i++;
  1706.         }
  1707.     }
  1708.     
  1709.     if (j > 1)                                /* if it doesn't end in EOL, count last line */
  1710.         tall++;
  1711.     
  1712. /*
  1713. *  Are we going to have enough memory to do this?
  1714. *  4 bytes for each data point in floating point.
  1715. */
  1716.     if ( wide < 2 || tall < 2 || checkmem((wide+1)*(tall+1)*4+1000) ) {
  1717.         HUnlock(txth);
  1718.         DisposHandle(txth);
  1719.         return(-1);
  1720.     }
  1721.  
  1722.     if (NULL == (td = newdatawin("Untitled",wide,tall))) {
  1723.         HUnlock(txth);
  1724.         DisposHandle(txth);
  1725.         return(-1);
  1726.     }
  1727.     
  1728.     strcpy(td->fname,"Untitled");
  1729.     td->needsave = 1;
  1730.  
  1731.     tempw = (struct Mwin *)NewPtr(sizeof(struct Mwin));
  1732.         
  1733.     tempw->dat = td;                /* point to same dataset */
  1734.     tempw->dat->refcount++;            /* increase refcount bookkeeping */
  1735.     
  1736.     tw = tempw;                        /* move to this element of list */
  1737.  
  1738. /*
  1739. *  the data array, read from the data space.
  1740. */
  1741.     f = td->vals;
  1742.     p = pstart;
  1743.  
  1744.     for (i=0; i< tall; i++) {
  1745.         if (calcidle()) {
  1746.             losedat(td);
  1747.             DisposPtr((Ptr) tw);
  1748.             HUnlock(txth);
  1749.             DisposHandle(txth);                /* don't need text memory anymore */
  1750.             return(-1);
  1751.         }
  1752.         
  1753.         for (j=0; j<wide; j++) {
  1754.  
  1755.             while (*p == ' ' || *p == 9)    /* skip white space, but not EOL */
  1756.                 p++;
  1757.  
  1758.             if (*p == 13) {                    /* don't bother sscanf if we are at EOL, leave 0.0 */
  1759.                 if (j)
  1760.                     *f++ = 0.0;                /* missing number in set */
  1761.                 else {
  1762.                     i--;
  1763.                     break;                    /* blank line, break out of loop, don't count it */
  1764.                 }
  1765.             }
  1766.             else
  1767.                 {
  1768.                 *f = atof ((const char *) p);
  1769.                 f++;
  1770.                 }
  1771.                 /*sscanf(p,"%e",f++);            /* get the number */
  1772.             
  1773.             while (*p > ' ')                /* skip the number, but not white space or EOL */
  1774.                 p++;
  1775.         }
  1776.         
  1777.         p++;
  1778.     }
  1779.  
  1780.     HUnlock(txth);
  1781.     DisposHandle(txth);                /* don't need pic memory anymore */
  1782.  
  1783.     f = td->yvals;
  1784.     for (i=0; i<tall ; i++)
  1785.         *f++ = (float)i;                    /* defaults for the scales */
  1786.  
  1787.     f = td->xvals;
  1788.     for (i=0; i<wide ; i++)
  1789.         *f++ = (float)i;                    /* defaults for the scales */
  1790.  
  1791.  
  1792. /*
  1793. *  If we get this far, then we assume things are ok and we start 'er up.
  1794. */
  1795.     maxmin( td->vals, wide, tall,
  1796.             &td->valmax, &td->valmin, 0,0, tall, wide);
  1797.  
  1798.     ctextwin(td);
  1799.  
  1800.     return(0);
  1801. }
  1802.